package com.ymt.fmd.platform.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

import com.ymt.fmd.appboot.prop.CacheConst;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.ymt.fmd.platform.dao.mysql.PFormHistoryMapper;
import com.ymt.fmd.platform.dao.mysql.PFormMapper;
import com.ymt.fmd.platform.dao.mysql.PFormVersionMapper;
import com.ymt.fmd.platform.formdesigner.parser.AbstractJsParser;
import com.ymt.fmd.platform.formdesigner.parser.ParserManager;
import com.ymt.fmd.platform.model.PForm;
import com.ymt.fmd.platform.model.PFormHistory;
import com.ymt.fmd.platform.model.PFormHistoryKey;
import com.ymt.fmd.platform.model.PFormHistoryWithBLOBs;
import com.ymt.fmd.platform.model.PFormVersion;
import com.ymt.fmd.platform.model.PFormVersionKey;
import com.ymt.fmd.util.Const;
import com.ymt.fmd.util.DateUtil;
import com.ymt.fmd.util.DhxUtil;


@Service
public class FmdService {
	
	private Logger logger = Logger.getLogger(FmdService.class.getName());
	
	@Autowired
	private PFormMapper fDao;
	
	@Autowired
	private PFormVersionMapper fvDao;
	
	@Autowired
	private PFormHistoryMapper fhDao;

	@Autowired
	private ParserManager parserManager;

	@Autowired
	private FmdCacheService fmdCacheService;
	
	
	public String[] newForm(String tenantId, String loginName, 
			String displayName, String param) {
		JSONObject p = JSONObject.parseObject(param);
		logger.finer("newForm saving new form...");
		String formid = "FORM-" + UUID.randomUUID().toString();
		String versionid = "0";
		
		PForm form = new PForm();
		if (tenantId!=null) {
			form.setTenantId(Integer.parseInt(tenantId));
		}
		form.setFormid(formid);
		form.setCreator(loginName);
		form.setCreatorname(displayName);
		Date createtime = DateUtil.getGMTDate();
		form.setCreatetime(createtime);
		form.setFormname(p.getString("name"));
		form.setFormdesc(p.getString("desc"));
		form.setFormtype(p.getString("type"));
		form.setStatus(PForm.STATUS_ACTIVE);
		PFormVersion version = new PFormVersion();
		version.setFormid(formid);
		if (tenantId!=null) {
			version.setTenantId(Integer.parseInt(tenantId));
		}
		version.setCreatetime(createtime);
		version.setUpdatetime(createtime);
		version.setCreator(loginName);
		version.setCreatorname(displayName);
		version.setCheckoutby(loginName);
		version.setCheckoutbyname(displayName);
		version.setVersionid(versionid);
		version.setStatus(PFormVersion.STATUS_ACTIVE);
		version.setIsdefault(Const.FALSE0);
		version.setVersionname(PFormVersion.CURRENT);
		String formdata = "{\"formconf\":{\"tabs\":[{\"id\":\"fmcontainer_tab_1\",\"compType\":\"layout\",\"type\":\"tab\",\"tabtype\":\"business\",\"title\":\"未命名\",\"items\":[{\"id\":\"fmcontainer_block_1\",\"compType\":\"layout\",\"type\":\"div12block\",\"pattern\":\"div12\",\"items\":[{\"compType\":\"layout\",\"type\":\"div12row\",\"items\":[{\"id\":\"ui-id-1\",\"compType\":\"layout\",\"items\":[],\"type\":\"div12cell\",\"fmdcols\":\"12\"}]}],\"maxspans\":0}]}]},\"propconf\":{\"fmcontainer_tab_1\":{\"id\":\"fmcontainer_tab_1\",\"i18nname-zh\":\"未命名\",\"i18nname-en\":\"Untitled\",\"display\":\"displayblock\",\"classNames\":\"\",\"style\":\"\",\"click\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"mouseenter\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"mouseleave\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"onactive\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e,obj\"}},\"fmcontainer_block_1\":{\"id\":\"fmcontainer_block_1\",\"i18nname-zh\":\"未命名\",\"i18nname-en\":\"Untitled\",\"display\":\"displayblock\",\"classNames\":\"\",\"style\":\"\",\"pattern\":\"div12\",\"margintop\":\"0.7\",\"noheader\":\"0\",\"fold\":\"0\",\"hidefor\":null,\"click\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"mouseenter\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"mouseleave\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e\"},\"onCollapse\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e,obj\"},\"onExpand\":{\"proptype\":\"event\",\"value\":\"\",\"arguments\":\"e,obj\"}},\"ui-id-1\":{\"id\":\"ui-id-1\"}},\"settings\":{\"advancedview\":false,\"fontsize\":16,\"canvas_size_widthem\":60,\"autohideprop\":true,\"tabpageidx\":2,\"contidx\":2,\"uiidx\":2},\"models\":{},\"refscript\":\"\",\"readyscript\":\"\",\"bodyscript\":\"\",\"datareadyscript\":\"\"}";
		version.setFormdata(formdata);
		fDao.insert(form);
		fvDao.insert(version);
		
		logger.finer("newForm return formid="+formid);
		return new String[]{formid, versionid};
	}

	public String[] saveForm(String tenantId, String loginName,
			String displayName, String param) {
		JSONObject p = JSONObject.parseObject(param);
		JSONObject f = p.getJSONObject("form");
		String formid = f.getString("formid");
		String versionid = null;
		
		if (formid==null || formid.length()==0) {//save new form
			logger.finer("saveForm saving new form...");
			formid = "FORM-" + UUID.randomUUID().toString();
			PForm form = new PForm();
			if (tenantId!=null) {
				form.setTenantId(Integer.parseInt(tenantId));
			}
			form.setFormid(formid);
			form.setCreator(loginName);
			form.setCreatorname(displayName);
			Date createtime = DateUtil.getGMTDate();
			form.setCreatetime(createtime);
			form.setFormname(f.getString("formname"));
			form.setFormdesc(f.getString("formdesc"));
			form.setFormtype(f.getString("formtype"));
			form.setStatus(PForm.STATUS_ACTIVE);
			PFormVersion version = new PFormVersion();
			version.setFormid(formid);
			if (tenantId!=null) {
				version.setTenantId(Integer.parseInt(tenantId));
			}
			version.setCreatetime(createtime);
			version.setUpdatetime(createtime);
			version.setCreator(loginName);
			version.setCreatorname(displayName);
			version.setCheckoutby(loginName);
			version.setCheckoutbyname(displayName);
			version.setVersionid("0");
			version.setStatus(PFormVersion.STATUS_ACTIVE);
			version.setIsdefault(Const.FALSE0);
			version.setVersionname(PFormVersion.CURRENT);
			logger.finer("saveForm version="+p.getJSONObject("version").toString());
			logger.finer("saveForm formdata str="+p.getJSONObject("version").getString("formdata"));
			version.setFormdata(p.getJSONObject("version").getString("formdata"));
			fDao.insert(form);
			fvDao.insert(version);
			versionid = version.getVersionid();
			
		} else {	//update existing form
			logger.finer("saveForm saving existing form...");
			JSONObject jv = p.getJSONObject("version");
			Date updatetime = DateUtil.getGMTDate();
			
			//set form
			PForm form = fDao.selectByPrimaryKey(formid);
			form.setFormname(f.getString("formname"));
			form.setFormdesc(f.getString("formdesc"));
			PFormVersionKey key = new PFormVersionKey();
			key.setFormid(formid);
			versionid = jv.getString("versionid");
			key.setVersionid(versionid);
			PFormVersion version = fvDao.selectByPrimaryKey(key);
			if (!"0".equals(versionid)) {//update version name and desc
				version.setVersionname(jv.getString("versionname"));
				version.setVersiondesc(jv.getString("versiondesc"));
			}
			
			//set history
			PFormHistoryWithBLOBs his = new PFormHistoryWithBLOBs();
			his.setChangeuserid(loginName);
			his.setChangeusername(displayName);
			his.setFormid(formid);
			his.setVersionid(versionid);
			his.setUpdatetime(updatetime);
			his.setIsautosave(p.getString("isautosave"));
			his.setFormdata(version.getFormdata());
			his.setChangeno(Integer.parseInt(fhDao.getMaxChangeno(formid, versionid).get("MAX").toString())+1);
			
			//set version new value
			version.setUpdatetime(updatetime);
			version.setIsdefault(jv.getString("isdefault"));
			String status = jv.getString("status");
			if (status==null || status.length()==0) {
				status = PFormVersion.STATUS_ACTIVE;
			}
			version.setStatus(status);
			logger.finer("saveForm formdata str="+jv.getString("formdata"));
			version.setFormdata(jv.getString("formdata"));
			
			fDao.updateByPrimaryKeySelective(form);
			fvDao.updateByPrimaryKeySelective(version);
			fhDao.insert(his);
			
		}
		logger.finer("saveForm return formid="+formid);

		//@CacheEvict 手动清除
		String cacheKey = fmdCacheService.asKey(CacheConst.CACHEKEY_PREFIX_FORM, tenantId, formid, versionid);
		fmdCacheService.remove(CacheConst.CACHE_NAME_FORM, cacheKey);

		return new String[]{formid, versionid};
	}
	
	/**
	 * update a form
	 * @param form
	 */
	public String updateForm(String form) {
		PForm f = (PForm)JSONObject.toJavaObject(JSONObject.parseObject(form), PForm.class);
		int rs = fDao.updateByPrimaryKeySelective(f);
		return "{\"result\":"+rs+"}";
	}
	
	/**
	 * delete a form, just change status to 02
	 * @param formid
	 */
	public String deleteForm(String formid) {
		if (isFormUsed(formid)) {
			return "{\"result\":-1}";
		}
		PForm form = fDao.selectByPrimaryKey(formid);
		form.setStatus(PForm.STATUS_DISCARD);
		int rs = fDao.updateByPrimaryKeySelective(form);
		return "{\"result\":"+rs+"}";
	}
	
	/**
	 * get a version
	 * @param formid
	 * @param versionid
	 * @return
	 */
	public String getVersion(String formid, String versionid) {
		PForm form = fDao.selectByPrimaryKey(formid);
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		JSONObject rtn = new JSONObject();
		rtn.put("form", JSONObject.toJSON(form));
		//试用alibaba JSON 需要单独解析formdata
		String formdata = version.getFormdata();
		version.setFormdata(null);
		JSONObject versionJo = (JSONObject)JSONObject.toJSON(version);
		versionJo.put("formdata", JSONObject.parse(formdata));
		rtn.put("version", versionJo);
		//rtn.put("version", JSONObject.toJSON(version));
		return rtn.toString();
	}
	
	/**
	 * delete a version
	 * @param formid
	 * @param versionid
	 * @return
	 */
	public String deleteVersion(String formid, String versionid) {
		if (isVersionUsed(formid, versionid)) {
			return "{\"result\":-1}";
		}
		PFormVersion version = new PFormVersion();
		version.setFormid(formid);
		version.setVersionid(versionid);
		version.setStatus(PFormVersion.STATUS_DISCARD);
		int rs = fvDao.updateByPrimaryKeySelective(version);
		return "{\"result\":"+rs+"}";
	}
	
	/**
	 * update version
	 * @param versionstr
	 * @return
	 */
	public String updateVersion(String versionstr, String loginName, String displayName) {
		PFormVersion version = (PFormVersion)JSONObject.toJavaObject(JSONObject.parseObject(versionstr), PFormVersion.class);
		version.setUpdatetime(DateUtil.getGMTDate());
		int rs = fvDao.updateByPrimaryKeySelective(version);
		return "{\"result\":"+rs+"}";
	}

	/**
	 * query form
	 * @param formstr
	 * @param fInd
	 * @param lInd
	 * @param timezoneOffset
	 * @param lang
	 * @param ordercolumns
	 * @return
	 */
	public String queryForm(String tenantId, String formstr, 
			int fInd, int lInd, int timezoneOffset, 
			String lang, String ordercolumns) {
		Map<String, Object> params = new HashMap<String,Object>();
		Map<String, Object> form = new HashMap<String,Object>();
		if (formstr!=null) {
			form.putAll(JSONObject.parseObject(formstr));
		}
		if (tenantId!=null) {
			form.put("tenantId", tenantId);
		}
		params.put("form", form);
		params.put("fromRow", fInd-1);
		params.put("toRow", lInd);
		params.put("rows", lInd - fInd + 1);
		params.put("timezoneOffset", timezoneOffset);
		params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));
		logger.finer("queryForm params="+params);
		List<Map<String,?>> list = fDao.pagingSelect(params);
		int total = Integer.parseInt(fDao.pagingSelectCount(params).get("COUNT").toString());
		String[] formCols = new String[]{"FORMID","FORMTYPE","FORMNAME","FORMDESC","CREATOR","CREATORNAME"};
		return DhxUtil.toGridJsonStr(list, 
				formCols, fInd, total, timezoneOffset, lang);
	}
	
	/**
	 * query version
	 * @param argstr
	 * @param fInd
	 * @param lInd
	 * @param timezoneOffset
	 * @param lang
	 * @param ordercolumns
	 * @return
	 */
	public String queryVersion(String argstr, int fInd, int lInd, int timezoneOffset, String lang, String ordercolumns) {
		Map<String, Object> params = new HashMap<String,Object>();
		Map<String, Object> args = new HashMap<String,Object>();
		if (argstr!=null) {
			args.putAll(JSONObject.parseObject(argstr));
		}
		params.put("args", args);
		params.put("fromRow", fInd-1);
		params.put("toRow", lInd);
		params.put("rows", lInd - fInd + 1);
		params.put("timezoneOffset", timezoneOffset);
		params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));
		logger.finer("queryVersion params="+params);
		List<Map<String,?>> list = fvDao.pagingSelect(params);
		int total = Integer.parseInt(fvDao.pagingSelectCount(params).get("COUNT").toString());
		String[] versionCols = new String[]{"VERSIONID","VERSIONNAME","VERSIONDESC","UPDATETIME","CHANGEUSERID","CHANGEUSERNAME",
				"CHECKOUTBY","CHECKOUTBYNAME","CREATOR","CREATORNAME","STATUS","FORMDATA"};
		return DhxUtil.toGridJsonStr(list, 
				versionCols, fInd, total, timezoneOffset, lang);
	}
	
	/**
	 * clone to new version
	 * @param loginName
	 * @param displayName
	 * @param formid
	 * @param versionid
	 * @param name
	 * @param desc
	 * @return
	 */
	public String toNewVersion(String tenantId, String loginName, String displayName, String formid, String versionid, String name, String desc) {
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		version.setVersionid(String.valueOf(fvDao.getMaxVersionid(formid)+1));
		version.setVersionname(name);
		version.setVersiondesc(desc);
		Date d = DateUtil.getGMTDate();
		version.setCreatetime(d);
		version.setUpdatetime(d);
		version.setCreator(loginName);
		version.setCreatorname(displayName);
		version.setCheckoutby(loginName);
		version.setCheckoutbyname(displayName);
		version.setStatus(PFormVersion.STATUS_ACTIVE);
		logger.finer("inserting version versionid="+versionid);
		fvDao.insertSelective(version);
		return "{\"result\":true, \"versionid\":\""+version.getVersionid()+"\"}";
	}
	
	/**
	 * clone to new readonly version
	 * @param loginName
	 * @param displayName
	 * @param formid
	 * @param versionid
	 * @param name
	 * @param desc
	 * @return
	 */
	public String toNewRoVersion(String tenantId, String loginName, String displayName, String formid, String versionid, String name, String desc) {
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		version.setVersionid(String.valueOf(fvDao.getMaxVersionid(formid)+1));
		version.setVersionname(name);
		version.setVersiondesc(desc);
		Date d = DateUtil.getGMTDate();
		version.setCreatetime(d);
		version.setUpdatetime(d);
		version.setCreator(loginName);
		version.setCreatorname(displayName);
		version.setCheckoutby(loginName);
		version.setCheckoutbyname(displayName);
		version.setStatus(PFormVersion.STATUS_ACTIVE);
		AbstractJsParser parser = parserManager.getParser();
		version.setFormdata(parser.toRoVersion(version.getFormdata()));
		logger.finer("inserting version versionid="+versionid);
		fvDao.insertSelective(version);
		return "{\"result\":true, \"versionid\":\""+version.getVersionid()+"\"}";
	}
	
	/**
	 * rename a version
	 * @param loginName
	 * @param displayName
	 * @param formid
	 * @param versionid
	 * @param name
	 * @param desc
	 * @return
	 */
	public String renameVersion(String tenantId, String loginName, String displayName, String formid, String versionid, String name, String desc) {
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		version.setVersionname(name);
		version.setVersiondesc(desc);
		Date d = DateUtil.getGMTDate();
		version.setUpdatetime(d);
		logger.finer("renameVersion version versionid="+versionid);
		int rs = fvDao.updateByPrimaryKeySelective(version);
		return "{\"result\":"+rs+"}";
	}
	
	/**
	 * clone to new form
	 * @param loginName
	 * @param displayName
	 * @param formid
	 * @param versionid
	 * @param name
	 * @param desc
	 * @return
	 */
	public String toNewForm(String tenantId, String loginName, String displayName, String formid, String versionid, String name, String desc) {
		//form
		PForm form = fDao.selectByPrimaryKey(formid);
		form.setFormid("FORM-" + UUID.randomUUID().toString());
		Date d = DateUtil.getGMTDate();
		form.setFormname(name);
		form.setFormdesc(desc);
		form.setCreatetime(d);
		form.setCreator(loginName);
		form.setCreatorname(displayName);
		form.setStatus(PForm.STATUS_ACTIVE);
		//version
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		version.setFormid(form.getFormid());
		version.setVersionid("0");
		version.setVersionname(PFormVersion.CURRENT);
		version.setVersiondesc(null);
		version.setCreatetime(d);
		version.setUpdatetime(d);
		version.setCreator(loginName);
		version.setCreatorname(displayName);
		version.setCheckoutby(loginName);
		version.setCheckoutbyname(displayName);
		version.setStatus(PFormVersion.STATUS_ACTIVE);
		fDao.insertSelective(form);
		fvDao.insertSelective(version);
		return "{\"result\":true, \"formid\":\""+form.getFormid()+"\", \"versionid\":\""+version.getVersionid()+"\"}";
	}
	
	/**
	 * query history
	 * @param argstr
	 * @param fInd
	 * @param lInd
	 * @param timezoneOffset
	 * @param lang
	 * @param ordercolumns
	 * @return
	 */
	public String queryHistory(String formid, String versionid, String argstr, int fInd, int lInd, int timezoneOffset, String lang, String ordercolumns) {
		Map<String, Object> params = new HashMap<String,Object>();
		Map<String, Object> args = new HashMap<String,Object>();
		if (argstr!=null) {
			args.putAll(JSONObject.parseObject(argstr));
		}
		params.put("formid", formid);
		params.put("versionid", versionid);
		params.put("his", args);
		params.put("fromRow", fInd-1);
		params.put("toRow", lInd);
		params.put("rows", lInd - fInd + 1);
		params.put("timezoneOffset", timezoneOffset);
		params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));
		logger.finer("queryHistory params="+params);
		List<Map<String,?>> list = fhDao.pagingSelect(params);
		int total = Integer.parseInt(fhDao.pagingSelectCount(params).get("COUNT").toString());
		String[] versionCols = new String[]{"FORMID","VERSIONID","CHANGENO","UPDATETIME","CHANGEUSERID","CHANGEUSERNAME"};
		return DhxUtil.toGridJsonStr(list, 
				versionCols, fInd, total, timezoneOffset, lang);
	}
	
	/**
	 * get a history
	 * @param formid
	 * @param versionid
	 * @param changeno
	 * @return
	 */
	public String getHistory(String formid, String versionid, String changeno) {
		PFormHistoryKey key = new PFormHistoryKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		key.setChangeno(Integer.parseInt(changeno));
		PFormHistory his = fhDao.selectByPrimaryKey(key);
		String rtn = JSONObject.toJSONString(his);
		logger.finer("getHistory rtn="+rtn);
		return rtn;
	}
	
	/**
	 * check if an user is the editor of a version
	 * @param formid
	 * @param versionid
	 * @return
	 */
	public boolean isEditor(String loginName, String formid, String versionid) {
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		return loginName.equalsIgnoreCase(version.getCheckoutby());
	}
	
	/**
	 * get a history
	 * @param formid
	 * @param versionid
	 * @return
	 */
	public String getVersionFormData(String formid, String versionid) {
		PFormVersion his = fvDao.getVersionFormData(formid, versionid);
		String rtn = JSONObject.parseObject(his.getFormdata()).toString();
		logger.finer("getHistory rtn="+rtn);
		return rtn;
	}
	
	/**
	 * export a version
	 * @param formid
	 * @param versionid
	 * @return
	 */
	public com.alibaba.fastjson.JSONObject exp(String formid, String versionid) {
		PForm form = fDao.selectByPrimaryKey(formid);
		PFormVersionKey key = new PFormVersionKey();
		key.setFormid(formid);
		key.setVersionid(versionid);
		PFormVersion version = fvDao.selectByPrimaryKey(key);
		com.alibaba.fastjson.JSONObject rtn = new com.alibaba.fastjson.JSONObject();
		rtn.put("form", com.alibaba.fastjson.JSONObject.toJSON(form));
		rtn.put("version", com.alibaba.fastjson.JSONObject.toJSON(version));
		return rtn;
	}

	/**
	 * export a version
	 * @param tenantId
	 * @param loginName
	 * @param displayName
	 * @param forceNew
	 * @param content
	 * @return
	 */
	public String imp(String tenantId, String loginName, String displayName,
			boolean forceNew, String content) {
		com.alibaba.fastjson.JSONObject rtn = new com.alibaba.fastjson.JSONObject();
		int rs = 0;
		com.alibaba.fastjson.JSONObject jo = com.alibaba.fastjson.JSONObject.parseObject(content);
		com.alibaba.fastjson.JSONObject formJo = jo.getJSONObject("form");
		com.alibaba.fastjson.JSONObject versionJo = jo.getJSONObject("version");
		PForm form = com.alibaba.fastjson.JSONObject.toJavaObject(formJo, PForm.class);
		PFormVersion version = com.alibaba.fastjson.JSONObject.toJavaObject(versionJo, PFormVersion.class);
		if (tenantId!=null && StringUtils.isNumeric(tenantId)) {
			form.setTenantId(Integer.parseInt(tenantId));
			version.setTenantId(Integer.parseInt(tenantId));
		}
		Date now = DateUtil.getGMTDate();
		form.setCreator(loginName);
		form.setCreatorname(displayName);
		form.setCreatetime(now);
		version.setCreator(loginName);
		version.setCreatorname(displayName);
		version.setCheckoutby(loginName);
		version.setCheckoutbyname(displayName);
		version.setCreatetime(now);
		version.setUpdatetime(now);
		version.setStatus(PFormVersion.STATUS_ACTIVE);
		version.setIsdefault(Const.FALSE0);
		PForm existingForm = fDao.selectByPrimaryKey(form.getFormid());
		if (existingForm==null) {
			//insert form and version
			version.setVersionid("0");
			version.setVersionname(PFormVersion.CURRENT);
			version.setVersiondesc(null);
			rs += fDao.insert(form);
			rs += fvDao.insert(version);
			rtn.put("newform", form.getFormname());
		} else if (forceNew) {
			//insert form and version
			if (form.getFormid().equals(existingForm.getFormid())) {
				String newFormId = "FORM-" + UUID.randomUUID().toString();
				form.setFormid(newFormId);
				version.setFormid(newFormId);
			}
			version.setVersionid("0");
			version.setVersionname(PFormVersion.CURRENT);
			version.setVersiondesc(null);
			rs += fDao.insert(form);
			rs += fvDao.insert(version);
			rtn.put("newform", form.getFormname());
		} else {
			//insert version only
			String newVersionId = String.valueOf(fvDao.getMaxVersionid(form.getFormid())+1);
			version.setVersionid(newVersionId);
			rs += fvDao.insert(version);
			rtn.put("newform", form.getFormname());
			rtn.put("newformid", form.getFormid());
			rtn.put("newversion", version.getVersionname());
		}
		rtn.put("result", rs);
		return rtn.toJSONString();
	}
	
	/**
	 * check if the form is in used
	 * @param formid
	 * @return
	 */
	private boolean isFormUsed(String formid) {
		return false;
	}
	
	/**
	 * check if the form is in used
	 * @param formid
	 * @return
	 */
	private boolean isVersionUsed(String formid, String versionid) {
		return false;
	}
	
}